/*
 * Copyright (c) 2006-2020, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-03-09     CGY       the first version
 */
#include "rtthread.h"
#include "rtdevice.h"
#include "board.h"

#define INIT_DUTY 4000
#define PWM_RADIO 4

static void TIM1_PWM_Out_Init(uint16_t Prescaler, uint16_t Period, uint16_t Pulse)
{
    GPIO_InitTypeDef GPIO_Initur = {0};

    __HAL_RCC_GPIOE_CLK_ENABLE();
    GPIO_Initur.Pin         = GPIO_PIN_9 | GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14;
    GPIO_Initur.Mode        = GPIO_MODE_AF_PP;
    GPIO_Initur.Pull        = GPIO_PULLUP;
    GPIO_Initur.Speed       = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_Initur.Alternate   = GPIO_AF1_TIM1;
    HAL_GPIO_Init(GPIOE, &GPIO_Initur);

/************************************定时器四个通道*******************************************/

    TIM_HandleTypeDef  TIM1_Handler = {0};
    TIM_OC_InitTypeDef TIM1_CH_Handler = {0};

    __HAL_RCC_TIM1_CLK_DISABLE();
    __HAL_RCC_TIM1_CLK_ENABLE();

    TIM1_Handler.Instance           = TIM1;
    TIM1_Handler.Init.Prescaler     = Prescaler;
    TIM1_Handler.Init.CounterMode   = TIM_COUNTERMODE_UP;
    TIM1_Handler.Init.Period        = Period;
    HAL_TIM_PWM_Init(&TIM1_Handler);

    TIM1_CH_Handler.OCMode=TIM_OCMODE_PWM1;
    TIM1_CH_Handler.Pulse= Pulse;
    TIM1_CH_Handler.OCPolarity=TIM_OCPOLARITY_HIGH;

    HAL_TIM_PWM_ConfigChannel(&TIM1_Handler,&TIM1_CH_Handler,TIM_CHANNEL_1);//配置TIM1通道1
    HAL_TIM_PWM_ConfigChannel(&TIM1_Handler,&TIM1_CH_Handler,TIM_CHANNEL_2);//配置TIM1通道2
    HAL_TIM_PWM_ConfigChannel(&TIM1_Handler,&TIM1_CH_Handler,TIM_CHANNEL_3);//配置TIM1通道3
    HAL_TIM_PWM_ConfigChannel(&TIM1_Handler,&TIM1_CH_Handler,TIM_CHANNEL_4);//配置TIM1通道4

    HAL_TIM_PWM_Start(&TIM1_Handler,TIM_CHANNEL_1);//开启PWM通道1
    HAL_TIM_PWM_Start(&TIM1_Handler,TIM_CHANNEL_2);//开启PWM通道2
    HAL_TIM_PWM_Start(&TIM1_Handler,TIM_CHANNEL_3);//开启PWM通道3
    HAL_TIM_PWM_Start(&TIM1_Handler,TIM_CHANNEL_4);//开启PWM通道4
}
static void TIM5_PWM_Out_Init(uint16_t Prescaler, uint16_t Period, uint16_t Pulse)
{
    GPIO_InitTypeDef GPIO_Initur = {0};
    __HAL_RCC_GPIOA_CLK_ENABLE();

    GPIO_Initur.Pin         = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3;
    GPIO_Initur.Mode        = GPIO_MODE_AF_PP;
    GPIO_Initur.Pull        = GPIO_PULLUP;
    GPIO_Initur.Speed       = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_Initur.Alternate   = GPIO_AF2_TIM5;
    HAL_GPIO_Init(GPIOA, &GPIO_Initur);

/************************************定时器四个通道*******************************************/

    TIM_HandleTypeDef  TIM5_Handler = {0};
    TIM_OC_InitTypeDef TIM5_CH_Handler = {0};

    __HAL_RCC_TIM5_CLK_DISABLE();
    __HAL_RCC_TIM5_CLK_ENABLE();

    TIM5_Handler.Instance           = TIM5;
    TIM5_Handler.Init.Prescaler     = Prescaler;
    TIM5_Handler.Init.CounterMode   = TIM_COUNTERMODE_UP;
    TIM5_Handler.Init.Period        = Period;
    HAL_TIM_PWM_Init(&TIM5_Handler);

    TIM5_CH_Handler.OCMode=TIM_OCMODE_PWM1;
    TIM5_CH_Handler.Pulse= Pulse;
    TIM5_CH_Handler.OCPolarity=TIM_OCPOLARITY_HIGH;

    HAL_TIM_PWM_ConfigChannel(&TIM5_Handler,&TIM5_CH_Handler,TIM_CHANNEL_1);//配置TIM5通道1
    HAL_TIM_PWM_ConfigChannel(&TIM5_Handler,&TIM5_CH_Handler,TIM_CHANNEL_2);//配置TIM5通道2
    HAL_TIM_PWM_ConfigChannel(&TIM5_Handler,&TIM5_CH_Handler,TIM_CHANNEL_3);//配置TIM5通道3
    HAL_TIM_PWM_ConfigChannel(&TIM5_Handler,&TIM5_CH_Handler,TIM_CHANNEL_4);//配置TIM5通道4

    HAL_TIM_PWM_Start(&TIM5_Handler,TIM_CHANNEL_1);//开启PWM通道1
    HAL_TIM_PWM_Start(&TIM5_Handler,TIM_CHANNEL_2);//开启PWM通道2
    HAL_TIM_PWM_Start(&TIM5_Handler,TIM_CHANNEL_3);//开启PWM通道3
    HAL_TIM_PWM_Start(&TIM5_Handler,TIM_CHANNEL_4);//开启PWM通道4
}
static void TIM4_PWM_Out_Init(uint16_t Prescaler, uint16_t Period, uint16_t Pulse)
{
    GPIO_InitTypeDef GPIO_Initur = {0};
    __HAL_RCC_GPIOD_CLK_ENABLE();         //开启GPIO时钟

    GPIO_Initur.Pin         = GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
    GPIO_Initur.Mode        = GPIO_MODE_AF_PP;
    GPIO_Initur.Pull        = GPIO_PULLUP;
    GPIO_Initur.Speed       = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_Initur.Alternate   = GPIO_AF2_TIM4;
    HAL_GPIO_Init(GPIOD, &GPIO_Initur);

/************************************定时器2的四个通道,分别对应四个电机*******************************************/

    TIM_HandleTypeDef  TIM4_Handler = {0};
    TIM_OC_InitTypeDef TIM4_CH_Handler = {0};

    __HAL_RCC_TIM4_CLK_DISABLE();
    __HAL_RCC_TIM4_CLK_ENABLE();

    TIM4_Handler.Instance           = TIM4;                         //定时器2
    TIM4_Handler.Init.Prescaler     = Prescaler;                    //定时器分频
    TIM4_Handler.Init.CounterMode   = TIM_COUNTERMODE_UP;           //向上计数模式
    TIM4_Handler.Init.Period        = Period;                       //自动重装载值
    HAL_TIM_PWM_Init(&TIM4_Handler);

    TIM4_CH_Handler.OCMode=TIM_OCMODE_PWM1;  //模式选择PWM1
    TIM4_CH_Handler.Pulse= Pulse;            //设置比较值,此值用来确定占空比,默认比较值为自动重装载值的一半,即占空比为50%
    TIM4_CH_Handler.OCPolarity=TIM_OCPOLARITY_HIGH; //输出比较极性为高

    HAL_TIM_PWM_ConfigChannel(&TIM4_Handler,&TIM4_CH_Handler,TIM_CHANNEL_1);//配置TIM4通道1
    HAL_TIM_PWM_ConfigChannel(&TIM4_Handler,&TIM4_CH_Handler,TIM_CHANNEL_2);//配置TIM4通道2
    HAL_TIM_PWM_ConfigChannel(&TIM4_Handler,&TIM4_CH_Handler,TIM_CHANNEL_3);//配置TIM4通道3
    HAL_TIM_PWM_ConfigChannel(&TIM4_Handler,&TIM4_CH_Handler,TIM_CHANNEL_4);//配置TIM4通道4

    HAL_TIM_PWM_Start(&TIM4_Handler,TIM_CHANNEL_1);//开启PWM通道1
    HAL_TIM_PWM_Start(&TIM4_Handler,TIM_CHANNEL_2);//开启PWM通道2
    HAL_TIM_PWM_Start(&TIM4_Handler,TIM_CHANNEL_3);//开启PWM通道3
    HAL_TIM_PWM_Start(&TIM4_Handler,TIM_CHANNEL_4);//开启PWM通道4
}

void Set_pwm(int16_t* pwm)
{
    TIM5->CCR1 = PWM_RADIO * ( pwm[0] ) + INIT_DUTY;//PA0    PWM-M1
    TIM5->CCR2 = PWM_RADIO * ( pwm[1] ) + INIT_DUTY;//PA1    PWM-M2
    TIM5->CCR3 = PWM_RADIO * ( pwm[2] ) + INIT_DUTY;//PA2    PWM-M3
    TIM5->CCR4 = PWM_RADIO * ( pwm[3] ) + INIT_DUTY;//PA3    PWM-M4

    TIM1->CCR1 = PWM_RADIO * ( pwm[4] ) + INIT_DUTY;//PE9    PWM-M5
    TIM1->CCR2 = PWM_RADIO * ( pwm[5] ) + INIT_DUTY;//PE10   PWM-M6
    TIM1->CCR3 = PWM_RADIO * ( pwm[6] ) + INIT_DUTY;//PE13   PWM-M7
    TIM1->CCR4 = PWM_RADIO * ( pwm[7] ) + INIT_DUTY;//PE14   PWM-M8

    TIM4->CCR1 = PWM_RADIO * ( 0 ) + INIT_DUTY;//PD12   PWM-M10
    TIM4->CCR2 = PWM_RADIO * ( 0 ) + INIT_DUTY;//PD13   PWM-M9
    TIM4->CCR3 = PWM_RADIO * ( 0 ) + INIT_DUTY;//PD14   PWM-M12
    TIM4->CCR4 = PWM_RADIO * ( 0 ) + INIT_DUTY;//PD15   PWM-M11
}

static int pwm_out_init(void)
{
    TIM4_PWM_Out_Init(21-1, 10000-1, 4000);//84M/21=4Mhz的计数频率,重装载值10000,所以PWM频率为 4M/10000=400Hz.
    TIM5_PWM_Out_Init(21-1, 10000-1, 4000);
    TIM1_PWM_Out_Init(42-1, 10000-1, 4000);

    return RT_EOK;
}

/* 导出到自动初始化 */
INIT_BOARD_EXPORT(pwm_out_init);
